#ifndef ROOTMINIMIZER_H_
#define ROOTMINIMIZER_H_

#include "StaticPointFCN.h"
#include "ToolMovementFCN.h"
#include "Minuit2/FunctionMinimum.h"
#include "Minuit2/MnUserParameterState.h"
#include "Minuit2/MnPrint.h"
#include "Minuit2/MnMigrad.h"
#include "Minuit2/MnMinos.h"
#include "Minuit2/MnSimplex.h"
#include "Minuit2/MnMinimize.h"
#include "Minuit2/MnContours.h"
#include "Minuit2/MnPlot.h"
#include <string>
#include <cmath>
#include "precom.h"

class RootMinimizer
{
public:
	RootMinimizer() : m_a(0.4), m_b(0.4), m_x(0.0), 
		m_y(0.0), m_z(0.0) {}

	bool Min(const MATHLIB::matrix33& a_surf,
		const MATHLIB::matrix33& a_tool);

	bool MinTool(const std::list<MATHLIB::vector3>& a_A,
		const std::list<MYFLOAT>& a_b);

	inline void SetA(MYFLOAT par) { m_a = static_cast<double>(par); }
	inline void SetB(MYFLOAT par) { m_b = static_cast<double>(par); }
	inline MYFLOAT A() { return static_cast<MYFLOAT>(m_a); }
	inline MYFLOAT B() { return static_cast<MYFLOAT>(m_b); }
	
	inline void SetPoint(const MATHLIB::vector3& vec) 
	{ 
		m_x = static_cast<double>(vec.x);
		m_y = static_cast<double>(vec.y);
		m_z = static_cast<double>(vec.z);
	}
	inline MATHLIB::vector3 Point() 
	{ 
		return MATHLIB::vector3(
			static_cast<MYFLOAT>(m_x),
			static_cast<MYFLOAT>(m_y),
			static_cast<MYFLOAT>(m_z));
	}
private:
	StaticPointFCN m_miniFun;
	ToolMovementFCN m_miniTool;
	double m_a, m_b;
	double m_x, m_y, m_z;
};

#endif //ROOTMINIMIZER_H_